const Emitter = require('events');
const { v4: uuidv4 } = require('uuid');

class LlmWorkerSession extends Emitter {
  constructor(llmWorker, sessionId) {
    super();
    this.llmWorker = llmWorker;
    this.sessionId = sessionId;//uuidv4();
  }

  // 发送给后端work
  sendJson(message) {
    const json = JSON.parse(message);
    json.timeStamp = Date.now();
    if(json.session_id === this.sessionId) {
      this.llmWorker.send(JSON.stringify(json));
      console.log("Send meesage to LLM Worker:", json);
    }else {
      console.log("LLM sensionID error");
    }
  }

  finish() {
    this.sendJson(JSON.stringify({ type: 'finish', timeStamp: Date.now(), session_id: this.sessionId}));
    this.llmWorker.removeSession(this.sessionId);
  }
}

class LlmWorker extends Emitter {
  constructor(ws, workerId) {
    super();
    this.sessions = new Map();
    this.workerId = workerId;
    this.ws = ws;
    this.initWebSocket();
  }

  initWebSocket() {
    this.ws.on('message', this.onMessage.bind(this));
    this.ws.on('close', this.onClose.bind(this));
    this.ws.on('error', this.onError.bind(this));
  }

  send(data) {
    this.ws.send(data);
  }

  onMessage(message) {
    try {
      const data = JSON.parse(message);
      const { type, state, content, session_id } = data;
      if (type === 'llm') {
        this.sessions.get(session_id).emit('llm', message);
      } else if (type === 'cmd') {
        console.log("llm work on error")
      }
    } catch (error) {
      console.error('解析消息时出错:', error);
    }
  }

  onClose() {
    this.emit('close');
  }

  onError(error) {
    console.error(`工作节点 ${this.workerId} 发生错误:`, error);
    this.emit('error', error);
  }

  newSession(sessionId) {
    const session = new LlmWorkerSession(this, sessionId);
    this.sessions.set(session.sessionId, session);
    return session;
  }

  removeSession(sessionId) {
    this.sessions.delete(sessionId);
  }

  close() {
    this.sessions.forEach(session => session.emit('close'));
    this.sessions.clear();
    this.ws.close();
  }
}

module.exports = LlmWorker;
